#include "RenderPch.h"

#include "ShaderToon2.h"
#include "Vector4.h"

ShaderToon2::ShaderToon2(void) :
ShaderBase()
{
	ShaderManager * shaderManager = RenderFacade::GetInstance()->Get3DRenderer()->GetShaderManager();
	m_pEffect = shaderManager->GetD3DEffect("toon2.fx");

	RenderFacade::GetInstance()->DXCreateTextureFromFile("Shader/toon.bmp", &m_pToonTexture);
	RenderFacade::GetInstance()->DXCreateTextureFromFile("Shader/ToonEdge.dds", &m_pEdgeTexture);
}

ShaderToon2::~ShaderToon2(void)
{
}

int ShaderToon2::Begin( Material * material, DWORD fvf )
{
	m_material = material;
	m_fvf = fvf;

	UINT passCount = 0;

	m_pEffect->SetTechnique( "ToonShader" );
	m_pEffect->Begin( &passCount, 0 );

	return passCount;
}

void ShaderToon2::BeginPass( int pass )
{
	if( pass == 0 )
	{
		RenderFacade::GetInstance()->SetFVF( m_fvf );

		RenderFacade::GetInstance()->SetTexture(0, m_pToonTexture);
		RenderFacade::GetInstance()->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
		RenderFacade::GetInstance()->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
		RenderFacade::GetInstance()->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);

		RenderFacade::GetInstance()->SetTexture(1, m_pEdgeTexture);
		RenderFacade::GetInstance()->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR);
		RenderFacade::GetInstance()->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
		RenderFacade::GetInstance()->SetTextureStageState(1, D3DTSS_COLOROP,  D3DTOP_MODULATE);
		RenderFacade::GetInstance()->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		RenderFacade::GetInstance()->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);

		Texture * texture = m_material->GetTextureData("diffuse_texture");

		if( texture )
		{
			RenderFacade::GetInstance()->SetTexture( 2, (LPDIRECT3DTEXTURE9)texture->Get() );
		}
		else
		{
			RenderFacade::GetInstance()->SetTexture( 2, NULL );
		}
		
		RenderFacade::GetInstance()->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_MODULATE);
		RenderFacade::GetInstance()->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		RenderFacade::GetInstance()->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_CURRENT);

		RenderFacade::GetInstance()->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
		RenderFacade::GetInstance()->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);

		RenderFacade::GetInstance()->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
		RenderFacade::GetInstance()->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
		RenderFacade::GetInstance()->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

		Matrix world, view, proj;
		RenderFacade::GetInstance()->GetTransform( D3DTS_WORLD, &world );
		RenderFacade::GetInstance()->GetTransform( D3DTS_VIEW, &view );
		RenderFacade::GetInstance()->GetTransform( D3DTS_PROJECTION, &proj );

		Matrix matWorldViewProj = world * view * proj;
		m_pEffect->SetMatrix( "matWorldViewProj", &matWorldViewProj );

		Vector4 lightDir = Vector4(0.f, 1.f, 0.f, 1.f);
		m_pEffect->SetVector( "vecLightDir", &lightDir );

		Matrix invView;
		view.GetInverse( invView );
		Vector4 eyePos = Vector4(invView._41, invView._42, invView._43, 1.f );
		m_pEffect->SetVector( "vecEyePos", &eyePos );

		m_pEffect->BeginPass( pass );
	}
}

void ShaderToon2::EndPass()
{
	m_pEffect->EndPass();

	RenderFacade::GetInstance()->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
	RenderFacade::GetInstance()->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
}

void ShaderToon2::End()
{
	m_pEffect->End();
}